package ren.steve.system.filter;

import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import ren.steve.common.result.HttpStatus;
import ren.steve.common.result.Result;
import ren.steve.common.utils.JwtHelper;
import ren.steve.common.utils.ResponseUtil;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: CIS-T-13 Liu GuoJia
 * @Description: Authentication
 * @Date: Created in 2024/2/7 11:41
 */

// 认证解析过滤器
public class TokenAuthenticationFilter extends OncePerRequestFilter {

  private RedisTemplate redisTemplate;

  public TokenAuthenticationFilter(RedisTemplate redisTemplate) {
    this.redisTemplate = redisTemplate;
  }

  @Override
  protected void doFilterInternal(
    HttpServletRequest request,
    HttpServletResponse response,
    FilterChain chain
  ) throws ServletException, IOException {
    logger.info("uri: " + request.getRequestURI());

    // 放行指定接口
    if ("/api/admin/login".equals(request.getRequestURI())) {
      chain.doFilter(request, response);
      return;
    }// 放行指定接口
    if ("/api/admin/captcha".equals(request.getRequestURI())) {
      chain.doFilter(request, response);
      return;
    }

    UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
    if (authentication != null) {
      SecurityContextHolder.getContext().setAuthentication(authentication);
      chain.doFilter(request,response);
    } else {
      ResponseUtil.out(response, Result.build(null, HttpStatus.UNAUTHORIZED));
    }
  }

  private UsernamePasswordAuthenticationToken getAuthentication (HttpServletRequest request) {
    String token = request.getHeader("token");
    logger.info("Token: " + token);
    if (!StringUtils.isEmpty(token)) {
      String userId = JwtHelper.getUserInfo(token, "id");
      String code = JwtHelper.getUserInfo(token, "code");
      String email = JwtHelper.getUserInfo(token, "email");
      String phone = JwtHelper.getUserInfo(token, "phone");
      logger.info("ID: " + userId);
      logger.info("Code: " + code);
      logger.info("EMail: " + email);
      logger.info("Phone: " + phone);

      if (!StringUtils.isEmpty(code)) {
        String authoritiesString = (String) redisTemplate.opsForValue().get(code);
        if (authoritiesString != null) {
          List<Map> mapList = JSON.parseArray(authoritiesString, Map.class);
          List<SimpleGrantedAuthority> authorities = new ArrayList<>();
          for (Map map : mapList) {
            authorities.add(new SimpleGrantedAuthority((String) map.get("authority")));
          }
          return new UsernamePasswordAuthenticationToken(code, null, authorities);
        }
      }
      // if (!StringUtils.isEmpty(email)) {
      //   return new UsernamePasswordAuthenticationToken(email, null);
      // }
      // if (!StringUtils.isEmpty(phone)) {
      //   return new UsernamePasswordAuthenticationToken(phone, null);
      // }
    }
    return null;
  }
}
